package com.uqpsoftware.uqplist;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import com.uqpsoftware.uqplist.tasks.Task;

public class DataPersistence {
	private static SharedPreferences sSharedPreferences;
	private static SharedPreferences.Editor sEditor;
	private static DataPersistence sDataPersistence;
	private final static String SPACER_SYMBOL = "&_#_&_#_FFJDJ#_#";
	private final static String KEY_FOR_PERSISTING_ALL_OF_THE_APPS_CURRENT_TABS = "TAB_LIST";
	private final static String CURRENT_ACTIVITY_ID_KEY = "ACTIVITY_ID_KEY";
	private final static String CURRENT_TASK_ID_KEY = "TAB_ID_KEY:";
	private final static String KEY_TO_HOLD_LIST_OF_A_TABS_CURRENT_TASK_IDS = "HOLD_LIST_OF_IDS:";
	private final static String INDIVIDUAL_TASK_KEY = "INDIVIDUAL_TASK_KEY:";
	private final static String KEY_FOR_PERSISTING_SELECTED_TAB = "PERSIST_SELECTED_TAB_KEY";
	private static Context sContext;
	List<TabList> mTabs = new ArrayList<TabList>();

	private DataPersistence() {
	}

	public static DataPersistence get(Context context) {
		if (sDataPersistence == null) {
			sDataPersistence = new DataPersistence();
			sContext = context;
			sSharedPreferences = context.getSharedPreferences("tabs", 0);
			sEditor = sSharedPreferences.edit();

		}
		return sDataPersistence;
	}

	public void persistSelectedTab(int tabID) {
		sEditor.putString(KEY_FOR_PERSISTING_SELECTED_TAB, "" + tabID);
		sEditor.commit();
	}

	public Integer getSelectedTab() {
		String selectedTabID = sSharedPreferences.getString(
				KEY_FOR_PERSISTING_SELECTED_TAB, "");
		if (selectedTabID == "") {
			return null;
		}
		return Integer.parseInt(selectedTabID);
	}

	public void persistActivityID(int ID) {
		sEditor.putString(CURRENT_ACTIVITY_ID_KEY, "" + ID);
		sEditor.commit();

	}

	public int getID() {
		String ID = sSharedPreferences.getString(CURRENT_ACTIVITY_ID_KEY, "0");
		return Integer.parseInt(ID);

	}

	public void persistTab(TabList tabToPersist) {

		Set<String> currentTabs = createSet(sSharedPreferences.getString(
				KEY_FOR_PERSISTING_ALL_OF_THE_APPS_CURRENT_TABS, ""));
		for (String tab : currentTabs) {
			try {
				if (new TabList(tab).getID() == tabToPersist.getID()) {
					currentTabs.remove(tab);
					break;
				}
			} catch (Exception e) {
				// something very very bad happened
				currentTabs.clear(); // clear the tabs and start over
				Log.e("UQP List Data Persistence",
						"persistTab Function: a string we got from sharedprefs must have been malformed");
			}
		}
		currentTabs.add(tabToPersist.toString());
		sEditor.putString(KEY_FOR_PERSISTING_ALL_OF_THE_APPS_CURRENT_TABS,
				createString(currentTabs));
		sEditor.commit();

	}

	public void unPersistTab(int tabID) {
		Set<String> currentTabs = createSet(sSharedPreferences.getString(
				KEY_FOR_PERSISTING_ALL_OF_THE_APPS_CURRENT_TABS, ""));
		String tabToErase = null;
		for (String tab : currentTabs) {
			try {
				if (new TabList(tab).getID() == tabID) {
					tabToErase = tab;
				}
			} catch (Exception e) {
				currentTabs.clear();
				Log.e("UQP List Data Persistence",
						"unPersistTab Function: a string we got from sharedprefs must have been malformed");
			}
		}
		if (tabToErase == null) {
			return;
		} else {
			currentTabs.remove(tabToErase);
		}
		sEditor.putString(KEY_FOR_PERSISTING_ALL_OF_THE_APPS_CURRENT_TABS,
				createString(currentTabs));
		sEditor.commit();

		removeTaskDataAssociatedWithATab(tabID);

	}

	public List<TabList> getTabs() {
		Set<String> currentTabs = createSet(sSharedPreferences.getString(
				KEY_FOR_PERSISTING_ALL_OF_THE_APPS_CURRENT_TABS, ""));
		List<TabList> listOfTabs = new ArrayList<TabList>();
		for (String s : currentTabs) {
			try {
				listOfTabs.add(new TabList(s));
			} catch (Exception e) {
				Log.e("UQP List Data Persistence",
						"unPersistTab Function: a string we got from sharedprefs must have been malformed");
			}
		}
		return listOfTabs;
	}

	public void persistListOfCurrentTaskIDs(int tabID, Set<String> taskIDs) {
		sEditor.putString(KEY_TO_HOLD_LIST_OF_A_TABS_CURRENT_TASK_IDS + tabID,
				createString(taskIDs));
		sEditor.commit();

	}

	private void removeTaskDataAssociatedWithATab(int tabID) {
		Set<String> tasksToRemove = getListOfCurrentTaskIDs(tabID);
		for (String task : tasksToRemove) {
			try {
				removeTask(new Task(task).getID());
			} catch (Exception e) {
				Log.e("UQP List Data Persistence",
						"removeTaskDataAssociatedWithATab: got a malformed string somehow.");
			}
		}
		sEditor.remove(KEY_TO_HOLD_LIST_OF_A_TABS_CURRENT_TASK_IDS + tabID);
		sEditor.commit();
	}

	public Set<String> getListOfCurrentTaskIDs(int tabID) {
		return createSet(sSharedPreferences.getString(
				KEY_TO_HOLD_LIST_OF_A_TABS_CURRENT_TASK_IDS + tabID, ""));

	}

	public Task getTask(int taskID) {
		String emptyString = "";
		String taskString = sSharedPreferences.getString(INDIVIDUAL_TASK_KEY
				+ taskID, emptyString);
		if (taskString.equals(emptyString)) {
			return null;
		} else {
			try {
				return new Task(taskString);
			} catch (Exception e) {
				Log.e("UQP List Data Persistence",
						"getTask function: got a malformed string somehow.");
				return null;
			}
		}
	}

	public void removeTask(int taskID) {
		sEditor.remove(INDIVIDUAL_TASK_KEY + taskID);
		sEditor.commit();
	}

	public void persistTask(Task taskToPersist) {
		sEditor.putString(INDIVIDUAL_TASK_KEY + taskToPersist.getID(),
				taskToPersist.toString());
		sEditor.commit();
	}

	public void persistCurrentTaskID(int tabID, int IDtoPersist) {
		sEditor.putString(CURRENT_TASK_ID_KEY, "" + IDtoPersist);
		sEditor.commit();
	}

	public int getCurrentTaskID(int tabID) {
		String currentID = sSharedPreferences.getString(CURRENT_TASK_ID_KEY,
				"0");
		return Integer.parseInt(currentID);
	}

	public String createString(Set<String> setToConvert) {
		String createdString = "";
		boolean firstTime = true;
		for (String s : setToConvert) {
			if (firstTime) {
				firstTime = false;
			} else {
				createdString = createdString + SPACER_SYMBOL;
			}
			createdString = createdString + s;
		}
		return createdString;
	}

	public Set<String> createSet(String serializedString) {
		if (serializedString.equals("")) {
			return new HashSet<String>();
		}
		String[] strings = serializedString.split(SPACER_SYMBOL);
		Set<String> createdSet = new HashSet<String>();
		for (String s : strings) {
			createdSet.add(s);
		}
		return createdSet;

	}

}
